package com.ruoyi.cmdb.util;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.ruoyi.cmdb.vo.SshExecRes;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;

//定义ssh利用私钥执行远程linux命令
public class SshByPrivateKeyExecution {
    public SshByPrivateKeyExecution(){};
    @SneakyThrows
    public SshExecRes executeCommandWithPrivateKey(String host, int port, String user, String privateKeyPath, String command) {
        StringBuilder output = new StringBuilder();
        int exitStatus = -1;
        JSch jsch = null;
        Session session = null;
        ChannelExec channelExec = null;
        InputStream in = null;

        try {
            jsch = new JSch();
            jsch.addIdentity(privateKeyPath); // 添加私钥

            session = jsch.getSession(user, host, port);
            session.setConfig("StrictHostKeyChecking", "no"); // 避免询问主机密钥确认
            session.connect();

            channelExec = (ChannelExec) session.openChannel("exec");
            channelExec.setCommand(command);

            // 获取命令的输出流
            in = channelExec.getInputStream();

            // 启动命令执行
            channelExec.connect();

            byte[] tmp = new byte[1024];
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0) break;
                    output.append(new String(tmp, 0, i));
                }
                if (channelExec.isClosed()) {
                    if (in.available() > 0) continue;
                    exitStatus = channelExec.getExitStatus();
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("Thread interrupted", e);
                }
            }
        } catch (JSchException | IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (channelExec != null) {
                    channelExec.disconnect();
                }
                if (session != null) {
                    session.disconnect();
                }
            } catch (IOException e) {
                // 忽略关闭资源时的异常
            }
        }
        SshExecRes sshExecRes=new SshExecRes(output.toString(),exitStatus);
        return sshExecRes;
    }
}
